package com.yfp.operation.utils;

import lombok.Data;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.*;

/**
 * @Description: 日期工具类
 *
 * @CreateDate: 2024/6/3 17:06
 * @UpdateUser:
 * @UpdateDate: 2024/6/3 17:06
 * @UpdateRemark: 暂无修改
 * @Version: 1.0
 */
public class DateUtils {

    /**
     * 计算时间和当前时间相差多少天
     * @param time
     * @return
     */
    public static long between(Date time){
        // 将Date转换为LocalDateTime
        LocalDateTime oldDateTime = time.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        // 获取当前时间的LocalDateTime
        LocalDateTime now = LocalDateTime.now();
        // 计算两个LocalDateTime之间的差异
        Duration duration = Duration.between(oldDateTime, now);

        // 输出相差的分钟数
        long between = duration.toMinutes();
        return  between;
    }

    /**
     * 获取当前时间
     * @return
     */
    public static Date getDate(){
        // 获取当前时间的LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.now();
        // 转换为Instant，默认在系统默认时区
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    /**
     * 获取当月自然周
     * @return
     */
    public static HashSet<Integer> getNaturalWeeksInMonth() {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 获取当前月份
        Month currentMonth = today.getMonth();
        // 获取当前年份
        int year = today.getYear();

        // 获取该月的第一天和最后一天
        LocalDate firstDayOfMonth = LocalDate.of(year, currentMonth, 1);
        LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());

        // 使用周一作为一周的第一天
        WeekFields weekFields = WeekFields.of(java.time.DayOfWeek.MONDAY, 1);

        // 创建一个 HashSet 来存储不同的周
        HashSet<Integer> weeks = new HashSet<>();

        // 遍历当前月的每一天
        for (LocalDate date = firstDayOfMonth; !date.isAfter(lastDayOfMonth); date = date.plusDays(1)) {
            // 获取当前日期的自然周数
            int weekNumber = date.get(weekFields.weekOfWeekBasedYear());
            weeks.add(weekNumber);
        }
        return weeks;
    }

    /**
     * 根据日期获取为当月的第几周
     * @param date
     * @return
     */
    public static int getWhichWeek(LocalDate date){
        // 获取当前月份的第一天
        LocalDate firstDayOfMonth = date.withDayOfMonth(1);

        // 使用周一作为一周的第一天
        WeekFields weekFields = WeekFields.of(java.time.DayOfWeek.MONDAY, 1);

        // 获取该日期在当月的周数
        int weekOfMonth = (date.get(weekFields.weekOfMonth()) - firstDayOfMonth.get(weekFields.weekOfMonth())) + 1;

        return weekOfMonth;
    }


    // date转LocalDate
    public static LocalDate convertToLocalDate(Date date) {
        // 将 Date 转换为 Instant
        Instant instant = date.toInstant();

        // 获取系统默认时区
        ZoneId zoneId = ZoneId.systemDefault();

        // 将 Instant 转换为 LocalDate
        return instant.atZone(zoneId).toLocalDate();
    }


    /**
     * 添加天数
     * @param timestamp
     * @param day
     * @return
     */
    public static Timestamp addDay(Timestamp timestamp, int day){
        BigDecimal multiply = new BigDecimal(day).multiply(new BigDecimal(86400000)).add(new BigDecimal(timestamp.getTime()));
        Timestamp timestamp1 = new Timestamp(multiply.longValue());
        return timestamp1;
    }

    /**
     * 添加天数
     * @param day
     * @return
     */
    public static String addDay(int day){
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        BigDecimal multiply = new BigDecimal(day).multiply(new BigDecimal(86400000)).add(new BigDecimal(timestamp.getTime()));
        Timestamp timestamp1 = new Timestamp(multiply.longValue());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String formattedDate = sdf.format(timestamp1);
        return formattedDate;
    }

    public static Timestamp[] getTomorrow(){
        Timestamp[] timestamps = new Timestamp[2];
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 1); // 将当前时间增加一天
        calendar.set(Calendar.HOUR_OF_DAY, 0); // 设置小时为0点
        calendar.set(Calendar.MINUTE, 0); // 设置分钟为0
        calendar.set(Calendar.SECOND, 0); // 设置秒为0
        calendar.set(Calendar.MILLISECOND, 0); // 设置毫秒为0
        Timestamp midnightTomorrow = new Timestamp(calendar.getTimeInMillis());
        timestamps[0] = midnightTomorrow;

        calendar.set(Calendar.HOUR_OF_DAY, 23); // 设置小时为0点
        calendar.set(Calendar.MINUTE, 59); // 设置分钟为0
        calendar.set(Calendar.SECOND, 59); // 设置秒为0
        Timestamp lastTomorrow = new Timestamp(calendar.getTimeInMillis());
        timestamps[1] = lastTomorrow;
        return timestamps;
    }

    /**
     * 日期字符串获取年龄
     * @param dateString
     * @return
     */
    public static Integer getAge(String dateString){
        // 创建DateTimeFormatter对象，指定字符串格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        // 使用formatter将字符串转换为LocalDate对象
        LocalDate date = LocalDate.parse(dateString, formatter);

        // 获取当前日期
        LocalDate currentDate = LocalDate.now();

        // 计算年龄
        Period age = Period.between(date, currentDate);

        return age.getYears();
    }


    /**
     * 与当前时间比较，是否小于7天以上
     * @param time
     * @return
     */
    public static boolean isExceedSevenDay(String time){

        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 将字符串转换为 LocalDateTime
        LocalDateTime givenDateTime = LocalDateTime.parse(time, formatter);

        // 将 LocalDateTime 转换为时间戳 (Instant)
        Instant givenInstant = givenDateTime.toInstant(ZoneOffset.UTC);

        // 获取当前时间的时间戳
        Instant currentInstant = Instant.now();

        // 计算时间戳差值，以秒为单位
        long secondsBetween = ChronoUnit.SECONDS.between(givenInstant, currentInstant);

        // 判断是否小于7天 (7天 = 7 * 24 * 60 * 60 秒)
        if (secondsBetween > 7 * 24 * 60 * 60) {
            return true;
        }
        return false;
    }




}